package com.bootx.service.impl;

import com.bootx.dao.LotteryRecordDao;
import com.bootx.entity.Config;
import com.bootx.entity.LotteryRecord;
import com.bootx.entity.OpenAiConfig;
import com.bootx.predict.pojo.PredictPlugin;
import com.bootx.predict.pojo.PredictionResult;
import com.bootx.predict.pojo.RedPacketBatch;
import com.bootx.service.*;
import com.bootx.util.JsonUtils;
import com.fasterxml.jackson.core.type.TypeReference;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author black
 */
@Service
public class LotteryRecordServiceImpl extends BaseServiceImpl<LotteryRecord,Long> implements LotteryRecordService {

    @Resource
    private LotteryRecordDao lotteryRecordDao;

    @Resource
    private LotteryRecordNumService  lotteryRecordNumService;

    @Resource
    private OpenAiConfigService openAiConfigService;
    @Resource
    private JdbcTemplate jdbcTemplate;

    @Resource
    private List<PredictPlugin> predictPlugins = new ArrayList<PredictPlugin>();

    @Resource
    private ConfigService configService;


    public LotteryRecord save(LotteryRecord lotteryRecord){
        LotteryRecord lotteryRecord1 = lotteryRecordDao.find("sn", lotteryRecord.getSn());
        if(lotteryRecord1==null){
            lotteryRecord1 = super.save(lotteryRecord);
        }else{
            lotteryRecord1.setDrawCode(lotteryRecord.getDrawCode());
            lotteryRecord1.setDrawTime(lotteryRecord.getDrawTime());
            lotteryRecord1 = super.update(lotteryRecord1);
        }
        List<Map<String, Object>> maps = lotteryRecordNumService.create(lotteryRecord1);
        if(!maps.isEmpty()){
            Config config = configService.find(2L);
            lotteryRecord1.setOpenInfo(JsonUtils.toJson(maps));
            // 获取到预测的是哪个位置
            String drawCode = lotteryRecord1.getDrawCode();
            String[] split = drawCode.split(",");
            int position = split.length-config.getWalletIndex();
            if(position>=0 && lotteryRecord1.getPredictResult()!=null){
                String s = split[position];
                lotteryRecord1.setWin(Integer.parseInt(s)%2==lotteryRecord1.getPredictResult());
            }
        }

        return super.update(lotteryRecord1);
    }

    @Override
    public void predict(Long lotteryCode,Long sn) {
        Config config = configService.find(2L);
        List<PredictPlugin> predictPluginList = predictPlugins.stream().filter(item -> StringUtils.equals(item.getName(), "basePredict")).toList();
        if(predictPluginList.isEmpty()){
            System.out.println("不存在该预测方法");
            return;
        }
        OpenAiConfig openAiConfig = openAiConfigService.find(1L);
        if (openAiConfig == null) {
            //System.out.println("apiKey没有配置");
            //return;
        }
        if (openAiConfigService.getCount() <= 0) {
            System.out.println("44444剩余次数没有了，请充值");
            return;
        }
        openAiConfigService.updateCount(-1*((int)Math.ceil((config.getPredictionCount()+0.0)/5)));
        List<Map<String, Object>> maps = jdbcTemplate.queryForList("SELECT * FROM (SELECT sn `batchId`,openInfo FROM lotteryrecord where lotteryCode=? and sn<? ORDER BY batchId DESC LIMIT ?) AS recent ORDER BY batchId ASC;", lotteryCode,sn,config.getPredictionCount());
        List<RedPacketBatch> list = new ArrayList<>();
        maps.forEach(map -> {
            RedPacketBatch redPacketBatch = new RedPacketBatch();
            redPacketBatch.setBatchId(Long.valueOf(map.get("batchId").toString()));
            List<RedPacketBatch.RedPacketDetail> redPackets = JsonUtils.toObject(map.get("openInfo")+"", new TypeReference<List<RedPacketBatch.RedPacketDetail>>() {
            });
            redPackets.sort(Comparator.comparingInt(RedPacketBatch.RedPacketDetail::getIndex));
            List<RedPacketBatch.RedPacketDetail> collect = redPackets.stream()
                    .sorted(Comparator.comparingInt(rp -> -rp.getIndex()))
                    .limit(config.getWalletIndex())
                    .sorted(Comparator.comparingInt(RedPacketBatch.RedPacketDetail::getIndex))
                    .collect(Collectors.toList());

            if(collect.size()<config.getWalletIndex()){
                System.out.println("红包数不够");
                return;
            }
            // 去掉最后几个
            for(int i=0;i<config.getWalletIndex()-1;i++){
                collect.removeLast();
            }
            int newIndex = 1000;
            for (RedPacketBatch.RedPacketDetail rp : collect) {
                rp.setIndex(newIndex++);
            }
            redPacketBatch.setRedPackets(collect);
            list.add(redPacketBatch);
        });
        Set<Integer> indexs = new HashSet<>();
        indexs.add(1000);
        for (int i = 0; i < list.size(); i++) {
            indexs.add(1000+i);
        }
        List<PredictionResult> results = predictPluginList.getFirst().predict(list,indexs);
        // 提取出概率最大的一项
        PredictionResult best = results.stream()
                .max(Comparator.comparingDouble(PredictionResult::getOddProbability))
                .orElse(null);
        assert best != null;
        LotteryRecord lotteryRecord = lotteryRecordDao.find("sn", sn);
        if(best.getOddProbability()<0.5){
            lotteryRecord.setPredictResult(0);
        } else if (best.getOddProbability()>=0.5) {
            lotteryRecord.setPredictResult(1);
        }
        // 获取到预测的是哪个位置
        lotteryRecord.setPredictPosition(1);
        super.update(lotteryRecord);
    }
}
